package com.zhou.framework.quartz.service.impl;

import com.zhou.framework.common.SpringFactory;
import com.zhou.util.PropertyUtil;
import com.zhou.framework.quartz.common.JobConfigCheck;
import com.zhou.framework.quartz.common.SchedulerManager;
import com.zhou.framework.quartz.config.QuartzConfig;
import com.zhou.framework.quartz.dto.JobPageDto;
import com.zhou.framework.quartz.dto.QuartzQueryDto;
import com.zhou.framework.quartz.mapper.QuartzMapper;
import com.zhou.framework.quartz.model.JobConfig;
import com.zhou.framework.quartz.service.QuartzService;
import lombok.extern.slf4j.Slf4j;
import org.quartz.CronTrigger;
import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Properties;

@Slf4j
@Service
public class QuartzServiceImpl implements QuartzService, ApplicationRunner {
    private SchedulerManager manager;
    @Autowired
    private QuartzMapper quartzMapper;
    @Autowired
    public QuartzServiceImpl(SchedulerManager manager){
        this.manager = manager;
    }

    @Override
    public List<JobPageDto> getPageList(QuartzQueryDto dto) {
        dto.setTablePrefix(QuartzConfig.tableFix);
        return quartzMapper.listJob(dto);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int resetTriggerStatus(String prefix) {
        return quartzMapper.resetTriggerStatus(prefix);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void createJob(JobConfig config) throws SchedulerException {
        manager.createJob(config);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void update(JobConfig config) throws SchedulerException {
        manager.updateJob(config,null);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void start() throws SchedulerException {
        manager.start();
    }
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void reLoad() throws Exception {
        Properties p = PropertyUtil.getProperties("quartz.properties","utf-8");
        manager.stop();
        SchedulerManager manager;
        if (QuartzConfig.enable){
            manager = new SchedulerManager(p);
        }else{
            manager = new SchedulerManager();
        }
        SpringFactory.removeBean("schedulerManager");

        this.manager = manager;
        manager.start();
        SpringFactory.registerBean("schedulerManager",manager);
    }
    @Override
    public JobConfig getJobByJobName(String jobName) throws SchedulerException {
        JobConfig config = JobConfigCheck.newJob(jobName);

        JobDetail d =  manager.getJobDetail(config);
        CronTrigger t = manager.getTrigger(config);
        if(d != null && t != null){
            config.setClazz(d.getJobClass());
            config.setCron(t.getCronExpression());
            return config;
        }
        return null;
    }
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void stop() throws SchedulerException {
        manager.stop();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void pauseJob(JobConfig config) throws SchedulerException {
        manager.pauseJob(config);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void startJob(JobConfig config) throws SchedulerException {
        manager.resumeJob(config);
    }
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteJob(JobConfig config) throws SchedulerException {
        manager.deleteJob(config);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int updateQuartzLogError() {
        return quartzMapper.updateQuartzLogError();
    }

    @Override
    public Scheduler getScheduler(){
        return manager.getScheduler();
    }

    @Override
    public void run(ApplicationArguments args) throws Exception {
        this.start();
        log.info("定时任务启动成功");
    }
}
